<?php

namespace App\Services\ApplyGoldProductSplit;

use Carbon\Carbon;
use App\Models\User;
use App\Models\GoldSplit;
use App\Models\GoldRecord;
use App\Models\GoldProduct;
use Brick\Math\RoundingMode;
use App\Services\HasHttpRequest;
use Illuminate\Support\Facades\Redis;

class ApplyGoldProductSplit
{
	protected User $user;

	protected ?GoldRecord $record = null;

	public function __construct(User $user, string $pendingCacheId)
	{
		$this->user = $user;
		$recordId = (int)Redis::hGet($pendingCacheId, 'gold_record_id');
		$record = $recordId > 0 ? GoldRecord::find($recordId) : null;
		$this->record = $record ?? null;
	}

	protected function deductSplitBeans()
	{
        $beans = $this->record->pay_gold_beans;
        $data = ['gold_record_id' => $this->record->id];
		account_beans($this->user)->minusSplitFeeBeans($beans, $data);
	}

    protected function newGoldProductStartedAt(): Carbon
    {
        $resellPeriod = (int)cs('storm')->gold_split_resell_period;

        $nextStartedAt = Carbon::today()->addDays($resellPeriod);

       /* $offWeekdays = cs('storm')->rest_weekdays;

        if (count($offWeekdays) <= 0) return $nextStartedAt;

        foreach ($offWeekdays as $offDay) {
            if ($offDay == 'Mon' and $nextStartedAt->isMonday()) {
                $nextStartedAt->addDay();
            } elseif ($offDay == 'Tue' and $nextStartedAt->isTuesday()) {
                $nextStartedAt->addDay();
            } elseif ($offDay == 'Wed' and $nextStartedAt->isWednesday()) {
                $nextStartedAt->addDay();
            } elseif ($offDay == 'Thu' and $nextStartedAt->isThursday()) {
                $nextStartedAt->addDay();
            } elseif ($offDay == 'Fri' and $nextStartedAt->isFriday()) {
                $nextStartedAt->addDay();
            } elseif ($offDay == 'Sat' and $nextStartedAt->isSaturday()) {
                $nextStartedAt->addDay();
            } elseif ($offDay == 'Sun' and $nextStartedAt->isSunday()) {
                $nextStartedAt->addDay();
            }
        }*/

        return $nextStartedAt;
    }

    protected function createNewGoldProduct()
    {
        $nextStartedAt = $this->newGoldProductStartedAt();

        $seed = $this->record->goldSeed;
        return GoldProduct::create([
            'gold_seed_id' => $seed->normal_gold_seed_id,
            'gold_round_id' => $seed->split_gold_round_id,
            'started_at' => $nextStartedAt,
        ]);
    }

     protected function createNewTransferGoldProduct()
    {
        $nextStartedAt = $this->newGoldProductStartedAt();

        $seed = $this->record->goldSeed;

        return GoldProduct::create([
            'gold_seed_id' => $seed->transfer_gold_seed_id,
            'gold_round_id' => $seed->transfer_gold_round_id,
            'started_at' => $nextStartedAt,
        ]);
    }

    protected function createGoldSplit(GoldProduct $goldProduct)
    {
        $record = $this->record;
        $seed = $record->goldSeed;

        $splitPrice = big_decimal($record->pay_net_price)
            ->dividedBy($seed->split_amount, 2, RoundingMode::HALF_UP);
        $splitProfit = big_decimal($record->profit_after_resold)
            ->dividedBy($seed->split_amount, 2, RoundingMode::HALF_UP);
        $splitBeans = big_decimal($record->pay_gold_beans)
            ->dividedBy($seed->split_amount, 2, RoundingMode::HALF_UP);

        $resellPeriod = (int)cs('storm')->gold_split_resell_period;

        GoldSplit::create([
            'user_id' => $record->user_id,
            'gold_round_id' => $record->gold_round_id,
            'gold_seed_id' => $record->gold_seed_id,
            'gold_product_id' => $record->gold_product_id,
            'product_id' => $record->product_id,
            'product_sku_id' => $record->product_sku_id,
            'split_record_id' => $record->id,
            'new_gold_product_id' => $goldProduct->id,
            'round' => $record->round,
            'gold_seed_title' => $record->goldSeed->title,
            'product_title' => $record->product->title,
            'sku_name' => $record->sku->name,
            'split_price' => $splitPrice,
            'split_profit' => $splitProfit,
            'split_beans' => $splitBeans,
            'started_at' => Carbon::today()->addDays($resellPeriod),
        ]);
    }

     protected function createGoldTransfer(GoldProduct $goldProduct)
    {
        $record = $this->record;
        $seed = $record->goldSeed;

        $splitPrice = big_decimal($record->pay_net_price)
            ->dividedBy(1, 2, RoundingMode::HALF_UP);
        $splitProfit = big_decimal($record->profit_after_resold)
            ->dividedBy(1, 2, RoundingMode::HALF_UP);
        $splitBeans = big_decimal($record->pay_gold_beans)
            ->dividedBy(1, 2, RoundingMode::HALF_UP);

        $resellPeriod = (int)cs('storm')->gold_split_resell_period;

        GoldSplit::create([
            'user_id' => $record->user_id,
            'gold_round_id' => $record->gold_round_id,
            'gold_seed_id' => $record->gold_seed_id,
            'gold_product_id' => $record->gold_product_id,
            'product_id' => $record->product_id,
            'product_sku_id' => $record->product_sku_id,
            'split_record_id' => $record->id,
            'new_gold_product_id' => $goldProduct->id,
            'round' => $record->round,
            'gold_seed_title' => $record->goldSeed->title,
            'product_title' => $record->product->title,
            'sku_name' => $record->sku->name,
            'split_price' => $splitPrice,
            'split_profit' => $splitProfit,
            'split_beans' => $splitBeans,
            'started_at' => Carbon::today()->addDays($resellPeriod),
        ]);
    }

	protected function splitGoldProduct()
	{
        $record = $this->record;
        $seed = $record->goldSeed;
        $splitsAmount = $seed->split_amount;

        $rate = $seed->transfer_rate;
        $nowRate = rand(0,100);

        if($rate >= $nowRate){
            $this->createGoldTransfer(
                    $this->createNewTransferGoldProduct()
                );
        }else{
            for ($i = 0; $i < $splitsAmount; $i++) {
                $this->createGoldSplit(
                    $this->createNewGoldProduct()
                );
            }

        }

        
	}

    protected function updateGoldRecord()
    {
        $goldRecord = $this->record;
        $goldProduct = $goldRecord->goldProduct;
        $goldRecord->update(['to_split_applied_at' => Carbon::now()]);
        $goldProduct->update(['disabled_at' => Carbon::now()]);
    }

	protected function split()
	{
        //$this->deductSplitBeans();
        $this->splitGoldProduct();
        $this->updateGoldRecord();

        $this->user->markRecordCacheAsSplit($this->record);

		return $this->record;
	}

	public function apply()
	{
		if (! $this->record) return null;

        return $this->split();
	}
}
